﻿using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using StarTrooper2DGameEngine;

namespace StarTrooper2DGame
{
    public partial class GamePage : PhoneApplicationPage
    {
        ContentManager contentManager;
        GameTimer timer;
        SpriteBatch spriteBatch;

        GraphicsDevice graphics;

        public static SpriteFont font;

        public static Texture2D BlankTexture;

        TimeSpan SpawnElapsedTime;
        TimeSpan CondorSpawnRate = TimeSpan.FromSeconds(5);

        UIElementRendererHelper uiRenderer;

        public GamePage()
        {
            InitializeComponent();

            // Get the content manager from the application
            contentManager = (Application.Current as App).Content;
            graphics = SharedGraphicsDeviceManager.Current.GraphicsDevice;

            // Create a timer for this page
            timer = new GameTimer();
            timer.UpdateInterval = TimeSpan.FromTicks(333333);
            timer.Update += OnUpdate;
            timer.Draw += OnDraw;

            GameState.Instance.ApplicationRestored = false;

            if (GameConstants.ParticlesEnabled)
            {
                //GameConstants.ParticleManager = new ParticleManager(ScreenManager.Current.game);
                //ScreenManager.Current.game.Components.Add(GameConstants.ParticleManager);
            }
            Loaded += GamePage_Loaded;
        }

        void GamePage_Loaded(object sender, RoutedEventArgs e)
        {
            AdRotatorControl.Invalidate();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Set the sharing mode of the graphics device to turn on XNA rendering
            graphics.SetSharingMode(true);

            // Construct after enabling XNA rendering
            uiRenderer = new UIElementRendererHelper(this);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(graphics);
            EngineAttributes.spriteBatch = spriteBatch;
            if (!GameState.Instance.ApplicationRestored)
            {
                GameState.Instance.NewGame();
                // TODO: use this.content to load your game content here
                LoadResources();

                AudioEngine.LoadContent(contentManager);

                //Try and load any saved key mappings
                FileManager.LoadKeyMappings();

                //If no settings present or setting were unable to be loaded, use the defaults
                if (!Input.InputMappings.SettingsSaved) Input.Load_Defaults();



                font = contentManager.Load<SpriteFont>(@"Fonts\SpriteFont1");

                GameConstants.ScoreText = new Text2D(font);
                GameConstants.ScoreText.Text = "Score: " + GameState.Instance.score.ToString();
                GameConstants.ScoreText.Position = new Vector2(10, 10);
                GameConstants.ScoreText.Color = Color.Red;
                GameFunctions.Add(GameConstants.ScoreText);

                GameConstants.ShotsText = new Text2D(font);
                GameConstants.ShotsText.Text = "Shots: " + GameState.Instance.shots.ToString();
                GameConstants.ShotsText.Position = new Vector2(150, 10);
                GameConstants.ShotsText.Color = Color.Red;
                GameFunctions.Add(GameConstants.ShotsText);

                BlankTexture = new Texture2D(graphics, 1, 1);
                BlankTexture.SetData(new Color[] { Color.White });

            }
            AudioEngine.PlayMusic();

            // Start the timer
            timer.Start();               
 
            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            AdRotatorControl.Dispose();

            // Stop the timer
            timer.Stop();

            AudioEngine.StopMusic();
            Input.Dispose();

            // Dispose before turning off XNA rendering
            uiRenderer.Dispose();

            // Set the sharing mode of the graphics device to turn off XNA rendering
            graphics.SetSharingMode(false);

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Allows the page to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        private void OnUpdate(object sender, GameTimerEventArgs e)
        {
            // TODO: Add your update logic here
            InternalUpdate(); // <- Added Sprite update function here

            SpawnElapsedTime += e.ElapsedTime;
            if (SpawnElapsedTime > CondorSpawnRate)
            {
                Condor condor = (Condor)GameConstants.Condor.Clone();
                condor.Position = new Vector2(GameFunctions.Random.Next(-100, (int)GameConstants.BackBufferWidth + 100), -150);
                GameState.Instance.m_AddedSprites.Add(condor);
                SpawnElapsedTime = TimeSpan.Zero;
            }
            GameConstants.ScoreText.Text = "Score: " + GameState.Instance.score.ToString();
            GameConstants.ShotsText.Text = "Shots: " + GameState.Instance.shots.ToString();

            Input.Update();
        }

        /// <summary>
        /// Allows the page to draw itself.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
            uiRenderer.PreRender();

            graphics.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            GameState.Instance.m_ZOrderedSprites.Sort(Sprite.ComparisonZOrder);// <- Added Sprite draw code here

            foreach (Sprite s in GameState.Instance.m_ZOrderedSprites)
                s.Draw(e.ElapsedTime, spriteBatch);

            foreach (Text2D t in GameState.Instance.m_Text2Ds)
                t.Draw(e.ElapsedTime, spriteBatch);

            uiRenderer.Draw();
        }

        #region Helper Functions


        void InternalUpdate()
        {
            foreach (Sprite s in GameState.Instance.m_AddedSprites)
            {
                GameState.Instance.m_Sprites.Add(s);
                GameState.Instance.m_ZOrderedSprites.Add(s);
            }
            GameState.Instance.m_AddedSprites.Clear();

            foreach (Sprite s in GameState.Instance.m_DeletedSprites)
            {
                GameState.Instance.m_Sprites.Remove(s);
                GameState.Instance.m_ZOrderedSprites.Remove(s);
            }
            GameState.Instance.m_DeletedSprites.Clear();

            foreach (Sprite s in GameState.Instance.m_Sprites)
                s.InternalUpdate();

            foreach (Sprite s in GameState.Instance.m_Sprites)
                s.Update();


            foreach (Text2D t in GameState.Instance.m_AddedText2Ds)
                GameState.Instance.m_Text2Ds.Add(t);
            GameState.Instance.m_AddedText2Ds.Clear();

            foreach (Text2D t in GameState.Instance.m_DeletedText2Ds)
                GameState.Instance.m_Text2Ds.Remove(t);
            GameState.Instance.m_DeletedText2Ds.Clear();

            foreach (Text2D t in GameState.Instance.m_Text2Ds)
                t.InternalUpdate();

        }

        public void LoadResources()
        {

            #region Background
            //Type the code here to add the background to the game.

            Texture2D background = contentManager.Load<Texture2D>(@"Pictures\background");

            Background bg = new Background(background);

            bg.Location = new Vector2(0, GameConstants.BackBufferHeight / 2);
            bg.ScaleX = GameConstants.BackBufferWidth / background.Width;
            bg.ScaleY = GameConstants.BackBufferHeight / background.Height;
            bg.ZOrder = 10;
            bg.Origin = Vector2.Zero;
            bg.Velocity = new Vector2(0, 1);

            GameState.Instance.m_AddedSprites.Add(bg);

            Background bg2 = (Background)bg.Clone();
            bg2.Location = new Vector2(0, -GameConstants.BackBufferHeight / 2);
            bg2.ScaleX = GameConstants.BackBufferWidth / background.Width;
            bg2.ScaleY = GameConstants.BackBufferHeight / background.Height;
            bg2.ZOrder = 10;

            GameState.Instance.m_AddedSprites.Add(bg2);

            #endregion

            #region Trooper
            //Type the code here to add the Trooper sprite.
            Trooper trooper = new Trooper(contentManager.Load<Texture2D>(@"Pictures\TrooperSpritesheet"), 6, true);

            trooper.Position = new Vector2(GameConstants.BackBufferWidth / 2, GameConstants.BackBufferHeight - (GameConstants.ScreenBuffer * 3));
            trooper.Speed = 4;
            GameState.Instance.m_AddedSprites.Add(trooper);

            GameState.Instance.Trooper = trooper;
            #endregion

            #region Condor
            //Type the code here to add the Condor sprite.
            Condor condor = new Condor();

            Animation condorAnimation = new Animation(contentManager.Load<Texture2D>(@"Pictures\CondorSpritesheet"), 4);

            condorAnimation.Play();
            condorAnimation.Loop = true;

            int[] ExplosionDelay = { 4, 3, 4 };
            Animation condorExplosion = new Animation(contentManager.Load<Texture2D>(@"Pictures\CondorExplosionSpritesheet"), 3, ExplosionDelay);

            condorExplosion.Play();

            condor.AddAnimation(condorAnimation);
            condor.AddAnimation(condorExplosion);
            GameConstants.Condor = condor;

            #endregion

            #region Fire
            GameConstants.Fire = new Fire(contentManager.Load<Texture2D>(@"Pictures\FireSpritesheet"), 2, true);
            GameConstants.Fire.ZOrder = -10;
            #endregion

        }
        #endregion

    }
}